'''
Created on 03-Apr-2010

@author: darsh
'''

from Util import util
from Util.util import debugmsg
from Config.KeyConfig import KeyConfig
from Xlib import X



class KeyBindingsManager():
    """
    This class contains the basic functionality for loading keybindings.It makes use of the KeyConfig class in WM.Config
    package and converts that into a for palatable to Xserver.
    """
    def __init__(self, defaultnamespace="default"):
        self.currentnamespace = defaultnamespace
        self.keybindings, self.namespacebindings, self.exitkey = KeyConfig.GetKeyBindings()
        debugmsg("SHOWING CURRENT KEYBINDINGS")
        debugmsg(self.keybindings)
        debugmsg("SHOWING CURRENT NAMESPACE BINDINGS")
        debugmsg(self.namespacebindings)
        debugmsg("SHOWING THE KEY USED FOR EXITING A NAMESPACE")
        debugmsg(self.exitkey)
        self.keyMap = {}
        self.nskeyMap = {}
        for i in self.namespacebindings:
            self.nskeyMap[(i[1], i[2])] = i
        for i in self.keybindings:
            self.keyMap[(i[0], i[1], i[5])] = i
        if self.currentnamespace == "default":
            self.grabdefaultmodekeys()
        else:
            self.grabnamespacekeys()



    def grabnamespacekeys(self):
        self.root.ungrab_key(X.AnyKey, X.AnyModifier)
        #grab namespace keys

        for binding in ([keyspec for keyspec in self.keybindings if keyspec[5] == self.currentnamespace]):
            code = self.disp.keysym_to_keycode(binding[0])
            self.root.grab_key(
                               code,
                               binding[1],
                               True,
                               X.GrabModeAsync,
                               X.GrabModeAsync
                               )

        #Grab the namespace exit key
        code = self.disp.keysym_to_keycode(self.exitkey[0])
        self.root.grab_key(
                           code,
                           self.exitkey[1],
                           True,
                           X.GrabModeAsync,
                           X.GrabModeAsync
                           )

    def grabdefaultmodekeys(self):
        self.root.ungrab_key(X.AnyKey, X.AnyModifier)
        for nsbinding in self.namespacebindings:
            code = self.disp.keysym_to_keycode(nsbinding[1])
            self.root.grab_key(
                               code,
                               nsbinding[2],
                               True,
                               X.GrabModeAsync,
                               X.GrabModeAsync
                               )
        for binding in [keyspec for keyspec in self.keybindings if keyspec[5] == self.currentnamespace]:
            if (binding[0], binding[1]) not in [(nsbinding[1], nsbinding[2]) for nsbinding in self.namespacebindings]:
                code = self.disp.keysym_to_keycode(binding[0])
                self.root.grab_key(
                                   code,
                                   binding[1],
                                   True,
                                   X.GrabModeAsync,
                                   X.GrabModeAsync
                                   )

    def switchtodefaultnamespace(self):
        util.message("Switching to namespace default")
        self.currentnamespace = "default"
        self.grabdefaultmodekeys()


    def switchtonamespace(self, namespace):
        util.message("Switching to namespace " + namespace)
        self.currentnamespace = namespace
        self.grabnamespacekeys()

    def HandleKeyPress(self, ev):

        #print >> sys.stderr ,"KEYPRESS ev IS BEING CHECKED"
        keysym = self.disp.keycode_to_keysym(ev.detail, 0)
        """
               Use keysym and modifier key pressed states as an index into a hashmap
               containing the keybinding structure
        """
        #EXIT FROM A NAMESPACE WHEN EXIT KEY IS PRESSED

        if self.exitkey[0] == keysym and self.exitkey[1] == ev.state and self.currentnamespace != "default":
            self.switchtodefaultnamespace()
            return
        #CHECK IN THE NAMESPACE KEYMAP BEFORE MOVING FURTHER .This is to prioritize the switching
        #to a namespace
        if self.currentnamespace == "default":
            ns = self.nskeyMap.get((keysym, ev.state))
            if ns:
                self.switchtonamespace(ns[0])

        k = self.keyMap.get((keysym, ev.state, self.currentnamespace))
        #print >> sys.stderr, k
        if not k:
            debugmsg("Ignoring unknown keysym: %s" % keysym)
            return
        """
               We have a valid key sequence.Use the toggle in 5th element
               to find which command to execute from command set in 3rd elememt
               of the WM's keybinding structure.After doing the work go ahead and
               increase the toggle
               Go ahead and increase the toggle
               """
        if k[3] == 1:
            self.Execute(k[2][0], k[2][1])
        else:
            self.Execute(k[2][k[4]][0], k[2][k[4]][1])
        k[4] = (k[4] + 1) % k[3]




    def HandleKeyBoardMapChange(self, ev):
        self.disp.refresh_keyboard_mapping(ev)
        if ev.request == X.MappingKeyboard:
            if self.currentnamespace == "default":
                self.switchtodefaultnamespace()
            else:
                self.switchtonamespace(self.currentnamespace)
